package com.open.basic.util;

import com.open.basic.exception.BizException;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


/**
 * @desc 文件工具类
 */
@Slf4j
public class FileUtils {

    private static final String patternString = "^[a-zA-Z\\d-/.]+$";
    private static final String patternString1 = "./|/.";

    private FileUtils() {
        throw new BizException("工具类不允许实例化");
    }

    /**
     * 文件路径验证
     *
     * @param path
     * @return
     * @throws IOException
     */
    public static void checkPath(String path) {
        if (path == null)
            return;
        if (path.contains("..")) {
            throw new BizException("路径非法");
        }
    }

    public static File getFile(String path) {
        checkPath(path);
        File file = new File(path);
        if (!file.exists()) {
            throw new BizException("文件不存在");
        }
        return file;
    }

    /**
     * 获取文件扩展名
     *
     * @param fileName
     * @return
     */
    public static String getFileExt(String fileName) {
        if (fileName == null) {
            return null;
        }
        int index = fileName.lastIndexOf(".");
        if (index == -1) {
            log.warn("文件名{}没有扩展名", fileName);
            return "";
        }
        return fileName.substring(index + 1);
    }


    /**
     * 创建目录
     *
     * @param path 文件路径
     * @throws IOException
     */
    public static void createDirs(String path) throws IOException {
        org.apache.commons.io.FileUtils.forceMkdir(new File(path));
    }

    /**
     * 创建临时文件
     *
     * @param fileName 文件名
     * @return
     * @throws IOException
     */
    public static File createTempFile(String fileName) throws IOException {
        File tempDirectory = org.apache.commons.io.FileUtils.getTempDirectory();
        if (!tempDirectory.exists()) {
            org.apache.commons.io.FileUtils.forceMkdir(tempDirectory);
        }
        String suffix = getFileExt(fileName);
        return File.createTempFile(fileName, suffix, tempDirectory);
    }

    /**
     * 删除文件
     *
     * @param file
     * @throws IOException
     */
    public static void deleteFile(File file) throws IOException {
        Files.deleteIfExists(file.toPath());
    }

    /**
     * 复制文件
     *
     * @param source
     * @param target
     * @throws IOException
     */
    public static void copyFile(File source, File target) throws IOException {
        org.apache.commons.io.FileUtils.copyFile(source, target);
    }

    /**
     * 重命名文件
     *
     * @param oldFile
     * @param newFile
     * @throws IOException
     */
    public static void renameFile(File oldFile, File newFile) throws IOException {
        if (!oldFile.exists()) {
            throw new IOException("原始文件不存在: " + oldFile.getAbsolutePath());
        }
        if (newFile.exists()) {
            throw new BizException("目标文件已存在: " + newFile.getAbsolutePath());
        }
        Files.move(oldFile.toPath(), newFile.toPath());
    }

    /**
     * 计算文件的MD5哈希值
     * @param filePath 文件路径
     * @return MD5哈希值
     * @throws IOException IO异常
     * @throws NoSuchAlgorithmException 算法异常
     */
    public static String calculateMD5(String filePath) throws IOException, NoSuchAlgorithmException {
        return calculateHash(filePath, "MD5");
    }

    /**
     * 计算文件的SHA-256哈希值
     * @param filePath 文件路径
     * @return SHA-256哈希值
     * @throws IOException IO异常
     * @throws NoSuchAlgorithmException 算法异常
     */
    public static String calculateSHA256(String filePath) throws IOException, NoSuchAlgorithmException {
        return calculateHash(filePath, "SHA-256");
    }

    /**
     * 计算文件的哈希值
     * @param filePath 文件路径
     * @param algorithm 算法名称
     * @return 哈希值
     * @throws IOException IO异常
     * @throws NoSuchAlgorithmException 算法异常
     */
    public static String calculateHash(String filePath, String algorithm) throws IOException, NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance(algorithm);
        try (FileInputStream fis = new FileInputStream(filePath)) {
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                digest.update(buffer, 0, bytesRead);
            }
        }

        byte[] hashBytes = digest.digest();
        StringBuilder sb = new StringBuilder();
        for (byte b : hashBytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}
